#!/usr/bin/env python3
"""
S3 Object Delete Tool - DeleteObject API 演示工具

这个工具演示如何使用 DeleteObject API 删除 S3 存储桶中的对象。

使用示例:
    python s3_object_delete.py --bucket my-bucket --key test.txt
    python s3_object_delete.py --bucket my-bucket --keys file1.txt file2.txt file3.txt
    python s3_object_delete.py --bucket my-bucket --keys file1.txt file2.txt --quiet
    python s3_object_delete.py --format json
    python s3_object_delete.py --verbose
"""

import argparse
import boto3
import json
import sys
from datetime import datetime, timezone
from botocore.config import Config
from botocore.exceptions import ClientError, NoCredentialsError


class ObjectDeleteClient:
    """S3 对象删除客户端"""
    
    def __init__(self, endpoint_url='http://localhost:8000', 
                 access_key='AKIAIOSFODNN7EXAMPLE', 
                 secret_key='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
                 region='us-east-1'):
        """
        初始化对象删除客户端
        
        Args:
            endpoint_url: S3 服务端点
            access_key: AWS Access Key
            secret_key: AWS Secret Key
            region: AWS 区域
        """
        self.endpoint_url = endpoint_url
        self.access_key = access_key
        self.secret_key = secret_key
        self.region = region
        self._client = None
    
    def _get_client(self):
        """获取 S3 客户端"""
        if self._client is None:
            self._client = boto3.client(
                's3',
                endpoint_url=self.endpoint_url,
                aws_access_key_id=self.access_key,
                aws_secret_access_key=self.secret_key,
                region_name=self.region,
                config=Config(s3={'addressing_style': 'path'})
            )
        return self._client
    
    def delete_single_object(self, bucket_name, key):
        """简单格式删除单个对象"""
        try:
            s3_client = self._get_client()
            
            print(f"🗑️  删除对象 s3://{bucket_name}/{key}")
            
            s3_client.delete_object(Bucket=bucket_name, Key=key)
            
            print(f"✅ 删除成功！")
            
            return True
            
        except ClientError as e:
            error_code = e.response['Error']['Code']
            error_msg = e.response['Error']['Message']
            
            if error_code == 'NoSuchBucket':
                print(f"❌ 桶不存在: {bucket_name}")
            else:
                print(f"❌ 删除失败 [{error_code}]: {error_msg}")
            
            return False
        except NoCredentialsError:
            print("❌ 错误: 未找到 AWS 凭据")
            return False
        except Exception as e:
            print(f"❌ 未知错误: {e}")
            return False
    
    def delete_single_object_verbose(self, bucket_name, key):
        """详细格式删除单个对象"""
        try:
            s3_client = self._get_client()
            
            print("🗑️  对象删除详细信息:")
            print("=" * 50)
            print(f"   🗂️  桶名称: {bucket_name}")
            print(f"   🔑 对象键名: {key}")
            print(f"   🌐 区域: {self.region}")
            print(f"   🔗 服务端点: {self.endpoint_url}")
            print(f"   📅 删除时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
            print()
            
            print(f"   🔧 正在删除对象...")
            s3_client.delete_object(Bucket=bucket_name, Key=key)
            
            print(f"   ✅ 删除成功！")
            print(f"   📊 删除完成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
            
            return True
            
        except ClientError as e:
            error_code = e.response['Error']['Code']
            error_msg = e.response['Error']['Message']
            
            print(f"   ❌ 删除失败:")
            print(f"      错误代码: {error_code}")
            print(f"      错误信息: {error_msg}")
            
            if error_code == 'NoSuchBucket':
                print(f"   📋 状态: 桶不存在")
            else:
                print(f"   📋 状态: 删除失败")
            
            return False
        except NoCredentialsError:
            print("   ❌ 错误: 未找到 AWS 凭据")
            return False
        except Exception as e:
            print(f"   ❌ 未知错误: {e}")
            return False
    
    def delete_single_object_json(self, bucket_name, key):
        """JSON 格式删除单个对象"""
        try:
            s3_client = self._get_client()
            
            s3_client.delete_object(Bucket=bucket_name, Key=key)
            
            result = {
                "success": True,
                "bucket_name": bucket_name,
                "key": key,
                "operation": "delete",
                "delete_time": datetime.now().isoformat()
            }
            
            print(json.dumps(result, indent=2, ensure_ascii=False))
            return True
            
        except ClientError as e:
            error_code = e.response['Error']['Code']
            error_msg = e.response['Error']['Message']
            
            result = {
                "success": False,
                "bucket_name": bucket_name,
                "key": key,
                "error": error_code,
                "error_message": error_msg,
                "delete_time": datetime.now().isoformat()
            }
            
            print(json.dumps(result, indent=2, ensure_ascii=False))
            return False
        except NoCredentialsError:
            result = {
                "success": False,
                "error": "NoCredentials",
                "error_message": "未找到 AWS 凭据",
                "delete_time": datetime.now().isoformat()
            }
            print(json.dumps(result, indent=2, ensure_ascii=False))
            return False
        except Exception as e:
            result = {
                "success": False,
                "error": "Unknown",
                "error_message": str(e),
                "delete_time": datetime.now().isoformat()
            }
            print(json.dumps(result, indent=2, ensure_ascii=False))
            return False
    
    def delete_multiple_objects(self, bucket_name, keys, quiet=False):
        """简单格式批量删除对象"""
        try:
            s3_client = self._get_client()
            
            objects = [{'Key': key} for key in keys]
            print(f"🗑️  批量删除 {len(objects)} 个对象")
            
            response = s3_client.delete_objects(
                Bucket=bucket_name,
                Delete={
                    'Objects': objects,
                    'Quiet': quiet
                }
            )
            
            deleted = response.get('Deleted', [])
            errors = response.get('Errors', [])
            
            if deleted:
                print(f"✅ 成功删除 {len(deleted)} 个对象：")
                for obj in deleted:
                    print(f"   • {obj['Key']}")
            
            if errors:
                print(f"❌ 删除失败 {len(errors)} 个对象：")
                for error in errors:
                    print(f"   • {error['Key']}: {error['Code']} - {error['Message']}")
            
            return len(errors) == 0
            
        except ClientError as e:
            error_code = e.response['Error']['Code']
            error_msg = e.response['Error']['Message']
            print(f"❌ 批量删除失败 [{error_code}]: {error_msg}")
            return False
        except NoCredentialsError:
            print("❌ 错误: 未找到 AWS 凭据")
            return False
        except Exception as e:
            print(f"❌ 未知错误: {e}")
            return False
    
    def delete_multiple_objects_verbose(self, bucket_name, keys, quiet=False):
        """详细格式批量删除对象"""
        try:
            s3_client = self._get_client()
            
            print("🗑️  批量对象删除详细信息:")
            print("=" * 50)
            print(f"   🗂️  桶名称: {bucket_name}")
            print(f"   📊 删除数量: {len(keys)}")
            print(f"   🌐 区域: {self.region}")
            print(f"   🔗 服务端点: {self.endpoint_url}")
            print(f"   📅 删除时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
            print(f"   🔇 安静模式: {'是' if quiet else '否'}")
            print()
            
            objects = [{'Key': key} for key in keys]
            print(f"   🔧 正在批量删除 {len(objects)} 个对象...")
            
            response = s3_client.delete_objects(
                Bucket=bucket_name,
                Delete={
                    'Objects': objects,
                    'Quiet': quiet
                }
            )
            
            deleted = response.get('Deleted', [])
            errors = response.get('Errors', [])
            
            print(f"   ✅ 删除完成！")
            print(f"   📊 成功删除: {len(deleted)} 个")
            print(f"   📊 删除失败: {len(errors)} 个")
            
            if deleted:
                print(f"\n   📋 成功删除的对象:")
                for obj in deleted:
                    print(f"      • {obj['Key']}")
            
            if errors:
                print(f"\n   📋 删除失败的对象:")
                for error in errors:
                    print(f"      • {error['Key']}: {error['Code']} - {error['Message']}")
            
            print(f"   📊 删除完成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
            
            return len(errors) == 0
            
        except ClientError as e:
            error_code = e.response['Error']['Code']
            error_msg = e.response['Error']['Message']
            
            print(f"   ❌ 批量删除失败:")
            print(f"      错误代码: {error_code}")
            print(f"      错误信息: {error_msg}")
            
            return False
        except NoCredentialsError:
            print("   ❌ 错误: 未找到 AWS 凭据")
            return False
        except Exception as e:
            print(f"   ❌ 未知错误: {e}")
            return False
    
    def delete_multiple_objects_json(self, bucket_name, keys, quiet=False):
        """JSON 格式批量删除对象"""
        try:
            s3_client = self._get_client()
            
            objects = [{'Key': key} for key in keys]
            
            response = s3_client.delete_objects(
                Bucket=bucket_name,
                Delete={
                    'Objects': objects,
                    'Quiet': quiet
                }
            )
            
            deleted = response.get('Deleted', [])
            errors = response.get('Errors', [])
            
            result = {
                "success": len(errors) == 0,
                "bucket_name": bucket_name,
                "operation": "batch_delete",
                "total_objects": len(keys),
                "deleted_count": len(deleted),
                "error_count": len(errors),
                "quiet_mode": quiet,
                "deleted_objects": [{"key": obj['Key']} for obj in deleted],
                "errors": [{"key": error['Key'], "code": error['Code'], "message": error['Message']} for error in errors],
                "delete_time": datetime.now().isoformat()
            }
            
            print(json.dumps(result, indent=2, ensure_ascii=False))
            return len(errors) == 0
            
        except ClientError as e:
            error_code = e.response['Error']['Code']
            error_msg = e.response['Error']['Message']
            
            result = {
                "success": False,
                "bucket_name": bucket_name,
                "operation": "batch_delete",
                "error": error_code,
                "error_message": error_msg,
                "delete_time": datetime.now().isoformat()
            }
            
            print(json.dumps(result, indent=2, ensure_ascii=False))
            return False
        except NoCredentialsError:
            result = {
                "success": False,
                "error": "NoCredentials",
                "error_message": "未找到 AWS 凭据",
                "delete_time": datetime.now().isoformat()
            }
            print(json.dumps(result, indent=2, ensure_ascii=False))
            return False
        except Exception as e:
            result = {
                "success": False,
                "error": "Unknown",
                "error_message": str(e),
                "delete_time": datetime.now().isoformat()
            }
            print(json.dumps(result, indent=2, ensure_ascii=False))
            return False


def parse_args():
    """解析命令行参数"""
    parser = argparse.ArgumentParser(
        description='S3 DeleteObject API 演示工具',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
示例:
  %(prog)s --bucket my-bucket --key test.txt                    # 删除单个对象
  %(prog)s --bucket my-bucket --keys file1.txt file2.txt        # 批量删除
  %(prog)s --bucket my-bucket --keys file1.txt file2.txt --quiet # 安静模式
  %(prog)s --format json                                        # JSON 格式输出
  %(prog)s --verbose                                            # 详细格式输出
  %(prog)s --access-key KEY --secret-key SECRET                 # 指定凭据
        """
    )
    
    parser.add_argument(
        '--host',
        default='http://localhost:8000',
        help='S3 服务端点 (默认: http://localhost:8000)'
    )
    
    parser.add_argument(
        '--access-key',
        default='AKIAIOSFODNN7EXAMPLE',
        help='AWS Access Key (默认: 测试密钥)'
    )
    
    parser.add_argument(
        '--secret-key',
        default='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
        help='AWS Secret Key (默认: 测试密钥)'
    )
    
    parser.add_argument(
        '--region',
        default='us-east-1',
        help='AWS 区域 (默认: us-east-1)'
    )
    
    parser.add_argument(
        '--format',
        choices=['simple', 'verbose', 'json'],
        default='simple',
        help='输出格式 (默认: simple)'
    )
    
    parser.add_argument(
        '--verbose',
        action='store_true',
        help='详细输出模式 (等同于 --format verbose)'
    )
    
    parser.add_argument(
        '--bucket',
        required=True,
        help='桶名称'
    )
    
    # 对象选择选项
    object_group = parser.add_mutually_exclusive_group(required=True)
    object_group.add_argument(
        '--key',
        help='对象键名（单个删除）'
    )
    
    object_group.add_argument(
        '--keys',
        nargs='+',
        help='对象键名列表（批量删除）'
    )
    
    parser.add_argument(
        '--quiet',
        action='store_true',
        help='安静模式（批量删除时不返回成功列表）'
    )
    
    return parser.parse_args()


def main():
    """主函数"""
    args = parse_args()
    
    # 如果指定了 --verbose，覆盖 format 设置
    if args.verbose:
        args.format = 'verbose'
    
    # 创建客户端
    client = ObjectDeleteClient(
        endpoint_url=args.host,
        access_key=args.access_key,
        secret_key=args.secret_key,
        region=args.region
    )
    
    # 根据格式执行相应操作
    success = False
    
    if args.key:
        # 单个删除
        if args.format == 'simple':
            success = client.delete_single_object_simple(args.bucket, args.key)
        elif args.format == 'verbose':
            success = client.delete_single_object_verbose(args.bucket, args.key)
        elif args.format == 'json':
            success = client.delete_single_object_json(args.bucket, args.key)
    else:
        # 批量删除
        if args.format == 'simple':
            success = client.delete_multiple_objects_simple(args.bucket, args.keys, args.quiet)
        elif args.format == 'verbose':
            success = client.delete_multiple_objects_verbose(args.bucket, args.keys, args.quiet)
        elif args.format == 'json':
            success = client.delete_multiple_objects_json(args.bucket, args.keys, args.quiet)
    
    # 设置退出码
    sys.exit(0 if success else 1)


if __name__ == '__main__':
    main()
